#!/bin/sh

########################################################################
# This test checks setting target name in runtime (but before the target
# has been loaded).
# 
# Usage: 
#   sh test.sh <target_dir>
#
# Target module should be <target_dir>/test_<target_dir>.ko
########################################################################
########################################################################
# A function to check prerequisites: whether the necessary files exist,
# etc.
########################################################################
checkPrereqs()
{
    #if test ! -f "${KEDR_MODULE}"; then
    #    printf "KEDR core module is missing: ${KEDR_MODULE}\n"
    #    exit 1
    #fi
    
    if test ! -f "${TARGET_MODULE}"; then
        printf "Target module is missing: ${TARGET_MODULE}\n"
        exit 1
    fi
    
    if test ! -f "${PAYLOAD_MODULE}"; then
        printf "Payload module is missing: ${PAYLOAD_MODULE}\n"
        exit 1
    fi
}

########################################################################
# Cleanup function
########################################################################
cleanupAll()
{
    cd "${WORK_DIR}"
    
    @LSMOD@ | grep "${TARGET_NAME_ACTUAL}" > /dev/null 2>&1
    if test $? -eq 0; then
        @RMMOD@ "${TARGET_NAME_ACTUAL}"
    fi
    
    @LSMOD@ | grep "${PAYLOAD_NAME}" > /dev/null 2>&1
    if test $? -eq 0; then
        @RMMOD@ "${PAYLOAD_NAME}"
    fi
    
    @LSMOD@ | grep "@KEDR_CORE_NAME@" > /dev/null 2>&1
    if test $? -eq 0; then
        @RMMOD@ "@KEDR_CORE_NAME@"
    fi
}

########################################################################
# Check if the string contents of the target_* parameters of the payload
# match the expected ones.
# Usage:
#   checkOutputStrings <expectedLoad> <expectedUnload>
########################################################################
checkOutputStrings()
{
    if test $# -ne 2; then
        printf "checkOutputStrings(): incorrect number of arguments\n"
        cleanupAll
        exit 1
    fi

    expectedLoad="$1"
    expectedUnload="$2"

    resultLoadString=$(cat "${OUT_LOAD_PARAM}")
    resultUnloadString=$(cat "${OUT_UNLOAD_PARAM}")
    if test "t${resultLoadString}" != "t${expectedLoad}"; then
        printf "\"Load\" string should have been \"${expectedLoad}\" "
        printf "but it is \"${resultLoadString}\".\n"
        cleanupAll
        exit 1
    fi

    if test "t${resultUnloadString}" != "t${expectedUnload}"; then
        printf "\"Unload\" string should have been \"${expectedUnload}\" "
        printf "but it is \"${resultUnloadString}\".\n"
        cleanupAll
        exit 1
    fi
}

########################################################################
# doTest() - preform the actual testing
########################################################################
doTest()
{
    @KEDR_CORE_LOAD_COMMAND@ || exit 1

    @INSMOD@ "${PAYLOAD_MODULE}" \
        set_load_fn=1 \
        set_unload_fn=1
    if test $? -ne 0; then
        printf "Failed to load the payload module\n"
        cleanupAll
        exit 1
    fi

    EXPECTED_LOAD_STRING="${TARGET_NAME_ACTUAL}"
    EXPECTED_UNLOAD_STRING="${TARGET_NAME_ACTUAL}"
    
    OUT_LOAD_PARAM="/sys/module/${PAYLOAD_NAME}/parameters/target_load_name"
    if test ! -e "${OUT_LOAD_PARAM}"; then
        printf "Parameter file does not exist: ${OUT_LOAD_PARAM}\n"
        cleanupAll
        exit 1
    fi

    OUT_UNLOAD_PARAM="/sys/module/${PAYLOAD_NAME}/parameters/target_unload_name"
    if test ! -e "${OUT_UNLOAD_PARAM}"; then
        printf "Parameter file does not exist: ${OUT_UNLOAD_PARAM}\n"
        cleanupAll
        exit 1
    fi
    
    # Set the target name now.
    echo "${TARGET_NAME}" > "/sys/module/@KEDR_CORE_NAME@/parameters/target_name"
    if test $? -ne 0; then
        printf "Failed to set target name.\n"
        cleanupAll
        exit 1
    fi

    @INSMOD@ "${TARGET_MODULE}"
    if test $? -ne 0; then
        printf "Initialization of the target module failed unexpectedly.\n"
        cleanupAll
        exit 1
    fi

    checkOutputStrings "${EXPECTED_LOAD_STRING}" "<none>"

    @RMMOD@ "${TARGET_NAME_ACTUAL}"
    if test $? -ne 0; then
        printf "Failed to unload the target module: ${TARGET_NAME}\n"
        cleanupAll
        exit 1
    fi
    
    checkOutputStrings "${EXPECTED_LOAD_STRING}" "${EXPECTED_UNLOAD_STRING}"
}

########################################################################
# main
########################################################################
WORK_DIR=${PWD}

if test $# -ne 1; then
    printf "Usage: sh test_set_target.sh <target_dir>\n"
    exit 1
fi

TARGET_DIR=$1

TARGET_NAME="test_${TARGET_DIR}"
TARGET_NAME_ACTUAL=$(echo "${TARGET_NAME}" | tr '-' '_')

TARGET_MODULE="${TARGET_DIR}/${TARGET_NAME}.ko"
printf "Target module: ${TARGET_MODULE}\n"

PAYLOAD_NAME="test_basics_payload"
PAYLOAD_MODULE="payload/${PAYLOAD_NAME}.ko"

################################
checkPrereqs
doTest
cleanupAll

# test passed
exit 0
